package com.hao.tool.extra.cloud.module.ali.fac;

import cn.hutool.core.io.FileUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectListing;
import com.hao.tool.extra.cloud.module.ali.entity.AlCosDTO;
import com.hao.tool.extra.cloud.module.ali.entity.AlCosResult;

import java.io.*;

/**
 * description
 *
 * @author RuiHaoZ on CMHK.jx
 * @date 2020-07-26 20:48
 */
public class AlCosFactory {

    private AlAccessToken alAccessToken;
    private AlCosDTO alCosDTO;

    private final static String endPoint = "https://oss-cn-beijing.aliyuncs.com";

    public AlCosFactory(AlAccessToken alAccessToken, AlCosDTO alCosDTO) {
        this.alAccessToken = alAccessToken;
        this.alCosDTO = alCosDTO;
    }


    /**
     * 上传文件
     *
     * @param fileDir     文件路径
     * @param fileName    文件名
     * @param inputStream 文件流
     * @return
     */
    public AlCosResult updateFile(String fileDir, String fileName, InputStream inputStream) {
        String bucketName = alCosDTO.getBucketName();
        // <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg。
        // 创建OSSClient实例。
        OSS ossClient = buildOssClient();
        // 上传文件到指定的存储空间（bucketName）并将其保存为指定的文件名称（objectName）。

        ossClient.putObject(bucketName, fileDir + fileName, inputStream);
        // 关闭OSSClient。
        ossClient.shutdown();
        return new AlCosResult().setAccessUrl(alCosDTO.getCosPrefixUrl() + fileDir + fileName);
    }

    /**
     * 删除文件
     *
     * @param objectName 文件名
     * @return
     */
    public AlCosResult deleteFile(String objectName) {
        String bucketName = alCosDTO.getBucketName();
        // <yourObjectName>表示删除OSS文件时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg。
        // 创建OSSClient实例。
        OSS ossClient = buildOssClient();
        // 删除文件。
        ossClient.deleteObject(bucketName, objectName);
        // 关闭OSSClient。
        ossClient.shutdown();
        return new AlCosResult();
    }

    /**
     * 下载文件
     *
     * @param objectName 文件名 hao-tool/xx/xx.jpg
     * @param filePath   本地保存地址
     * @return
     * @throws IOException
     */
    public AlCosResult downFile(String objectName, String filePath) throws IOException {

        String bucketName = alCosDTO.getBucketName();
        // <yourObjectName>从OSS下载文件时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg。
        // 创建OSSClient实例。
        OSS ossClient = buildOssClient();
        // 调用ossClient.getObject返回一个OSSObject实例，该实例包含文件内容及文件元信息。
        OSSObject ossObject = ossClient.getObject(bucketName, objectName);
        // 调用ossObject.getObjectContent获取文件输入流，可读取此输入流获取其内容。
        InputStream content = ossObject.getObjectContent();
        File file = null;
        if (content != null) {
            file = FileUtil.writeFromStream(content, filePath);
            // 数据读取完成后，获取的流必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。
            content.close();
        }
        // 关闭OSSClient。
        ossClient.shutdown();
        return new AlCosResult().setDownFile(file);
    }

    public AlCosResult listFile() {
        // Endpoint以杭州为例，其它Region请按实际情况填写。
        // 阿里云主账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维，请登录RAM控制台创建RAM账号。
        String bucketName = alCosDTO.getBucketName();
        // 创建OSSClient实例。
        OSS ossClient = buildOssClient();
        // ossClient.listObjects返回ObjectListing实例，包含此次listObject请求的返回结果。
        ObjectListing objectListing = ossClient.listObjects(bucketName);
        // objectListing.getObjectSummaries获取所有文件的描述信息。

        // 关闭OSSClient。
        ossClient.shutdown();
        return new AlCosResult().setListFile(objectListing.getObjectSummaries());
    }

    public OSS buildOssClient() {
        // 阿里云主账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维，请登录RAM控制台创建RAM账号。
        OSS ossClient = new OSSClientBuilder().build(endPoint,
                alAccessToken.getAccessKeyId(), alAccessToken.getAccessKeySecret());
        return ossClient;
    }


}
